#pragma once

#include "Primitive.h"
#include "Vector3.h"
#include "Vector4.h"
#include "Scene.h"
#include "Ray.h"

namespace RayTracer
{

	class CEngine
	{
	public:
		CEngine(const CVector3& cameraPosition, const CVector4& background, int MaxTraceDepth = 6, int waitTimer = 100 /*msecs*/);
		~CEngine(void);

		// Set the render target canvas
		void setTarget(int width, int height);

		// Get the pixel buffer
		float* getBuffer() { return m_Pixels; }

		// Naive approach: intersects ray with every primitive in the scene to determine closest intersection
		CPrimitive* RayTrace(CRay& ray, CVector4& acc, int traceDepth, float& rayDist);
		
		// Initializes the renderer
		void InitRender();

		// Shoots rays in the scene one scanline at a time, from left to right
		bool Render();

		Scene* getScene() { return m_Scene; }

	protected:
		int m_MaxTraceDepth;
		CVector4 m_Background;
		CVector3 m_CameraPosition;

		int m_WaitTimer;		// Time to wait before updating screen image, in msecs

		// Location in world space of image plane
		float m_WinX1;		// Start of window x_coord
		float m_WinY1;		// Start of window y_coord
		float m_WinX2;		// End of window x_coord
		float m_WinY2;		// End of window y_coord

		float m_DX;
		float m_DY;
		float m_SX;
		float m_SY;

		Scene* m_Scene;
		float* m_Pixels;	// Color values for pixels in image place
		
		int m_Width;		// width of scene
		int m_Height;		// height of scene
		int m_CurLine;		// Position of scanline in target canvas
		int m_PPos;			// Position of current pixel target canvas

		CPrimitive** m_LastRow;	// Array of primitives from previous row in image
	};

}